package org.arnetminer.personalized.dao;

import java.sql.SQLException;
import java.util.List;

import org.arnetminer.personalized.vo.Message;
import org.arnetminer.personalized.vo.Status;
import org.arnetminer.personalized.vo.User;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.HibernateTemplate;

/**
 	* A data access object (DAO) providing persistence and search support for User entities.
 			* Transaction control of the save(), update() and delete() operations 
		can directly support Spring container-managed transactions or they can be augmented	to handle user-managed Spring transactions. 
		Each of these methods provides additional information for how to configure it for the desired type of transaction control. 	
	 * @see org.arnetminer.personalized.vo.User
  * @author MyEclipse Persistence Tools 
 */

public class MessageDAOImpl extends BaseDAOImpl implements MessageDAO {
	private static final Logger log = LoggerFactory.getLogger(MessageDAOImpl.class);
	//property constants
	public static final String Message = "message";
	
	public void initDao() {
		
		super.initDao();
	}


	public void attachClean(Message instance) {
		
		super.attachClean(instance);
	}


	public void attachDirty(Message instance) {
		
		super.attachDirty(instance);
	}


	public void delete(Message persistentInstance) {
		
		super.delete(persistentInstance);
	}


	public List findByExample(Message instance) {
		
		return super.findByExample(instance);
	}


	public Object merge(Message detachedInstance) {
		
		return super.merge(detachedInstance);
	}


	public void save(Message transientInstance) {
		
		super.save(transientInstance);
	}


	public List findByProperties(final List<String> properties, final List values, final int start, final int max) {
	      log.debug("finding Message instance within range\n");
	      try {
		    	HibernateTemplate template = getHibernateTemplate();
		    	return template.executeFind(new HibernateCallback() {  
		            public Object doInHibernate(Session session) throws HibernateException, SQLException {
		            	try {
		            	Criteria criteria = session.createCriteria(Message.class);
		            	for (int i = 0; i < properties.size(); i++) {
		            		criteria.add(Restrictions.eq(properties.get(i), values.get(i)));
		    	    	}
		            	criteria.addOrder(Order.desc("sendDate"));
		            	criteria.setFirstResult(start);
		            	criteria.setMaxResults(max);
		            	return criteria.list();
		            	}
		            	catch(Exception ex) {
		            		ex.printStackTrace();
		            		return null;
		            	}
		            	finally {
		            		session.close();
		            	}
		            }  
		        });
		    } catch (RuntimeException re) {
		       log.error("find by property name failed", re);
		       throw re;
		    }
	}
	
	public List findByProperties(final List<String> properties, final List values) {
	      log.debug("finding Message instance within range\n");
	      try {
		    	HibernateTemplate template = getHibernateTemplate();
		    	return template.executeFind(new HibernateCallback() {  
		            public Object doInHibernate(Session session) throws HibernateException, SQLException {
		            	try {
		            	Criteria criteria = session.createCriteria(Message.class);
		            	for (int i = 0; i < properties.size(); i++) {
		            		criteria.add(Restrictions.eq(properties.get(i), values.get(i)));
		    	    	}
		            	criteria.addOrder(Order.desc("sendDate"));
		            	return criteria.list();
		            	}
		            	catch(Exception ex) {
		            		ex.printStackTrace();
		            		return null;
		            	}
		            	finally {
		            		session.close();
		            	}
		            }  
		        });
		    } catch (RuntimeException re) {
		       log.error("find by property name failed", re);
		       throw re;
		    }
	}
	
	public int findOutCountByUser(final User user, final int isDraft) {
	      log.debug("finding Message instance within range\n");
	      try {
		    	HibernateTemplate template = getHibernateTemplate();
		    	return template.execute(new HibernateCallback() {  
		            public Object doInHibernate(Session session) throws HibernateException, SQLException {
		            	try {
		            		Query query = session.createQuery("select count(*) from Message where sender = ? and isDraft = ? and inOrout = ?");
		            		query.setParameter(0, user);
		            		query.setParameter(1, isDraft);
		            		query.setParameter(2, 0);
		            		return Integer.parseInt(query.iterate().next().toString());
		            	}
		            	catch(Exception ex) {
		            		ex.printStackTrace();
		            		return null;
		            	}
		            	finally {
		            		session.close();
		            	}
		            }  
		        });
		    } catch (RuntimeException re) {
		       log.error("find by property name failed", re);
		       throw re;
		    }
	}
	
	public int findInCountByUser(final User user, final int isDraft) {
	      log.debug("finding Message instance within range\n");
	      try {
		    	HibernateTemplate template = getHibernateTemplate();
		    	return template.execute(new HibernateCallback() {  
		            public Object doInHibernate(Session session) throws HibernateException, SQLException {
		            	try {
		            		Query query = session.createQuery("select count(*) from Message where receiver = ? and isDraft = ? and inOrout = ?");
		            		query.setParameter(0, user);
		            		query.setParameter(1, isDraft);
		            		query.setParameter(2, 1);
		            		return Integer.parseInt(query.iterate().next().toString());
		            	}
		            	catch(Exception ex) {
		            		ex.printStackTrace();
		            		return null;
		            	}
		            	finally {
		            		session.close();
		            	}
		            }  
		        });
		    } catch (RuntimeException re) {
		       log.error("find by property name failed", re);
		       throw re;
		    }
	}
	
	public boolean delete(long id) {
		Session session = getHibernateTemplate().getSessionFactory().openSession();
		String hql = "DELETE FROM Message message WHERE id = " + id;
		try {
			Query query = session.createQuery(hql);
			int row = query.executeUpdate();
			if (row == 0)
				return false;
		}
		catch (Exception ex) {
			ex.printStackTrace();
			return false;
		}
		finally {
			session.close();
		}
		return true;
		
	}
	
	public Message findById(long id) {
        log.debug("getting Message instance with id: " + id);
        try {
        	Message instance = (Message) getHibernateTemplate()
                    .get("org.arnetminer.personalized.vo.Message", id);
            return instance;
        } catch (RuntimeException re) {
            log.error("get failed", re);
            throw re;
        }
    }
	
}